/*
	Copyright (c) 2007, ANYwebcam.com Pty Ltd. All rights reserved.

	The software in this package is published under the terms of the BSD style 
	license, a copy of which has been included with this distribution in the 
	license.txt file.
*/
package com.anywebcam.util
{
	import com.anywebcam.util.ArrayPeer;

	import flexunit.framework.TestCase;
	import flexunit.framework.TestSuite;

	public class ArrayPeerTest extends TestCase
	{
		public static function suite():TestSuite
		{
			var ts:TestSuite = new TestSuite();

			var tests:Array = 
			[
				'shouldFindWithSingleSimpleCondition',
				'shouldFindWithMultipleSimpleConditions',
				'shouldFindWithSimplePropertyChainCondtion',
				'shouldFindWithClassAsExpectedValue',
				'shouldFindWithFunctionAsExpectedValue',
				'shouldFindWithRegExpAsExpectedValue',
				'shouldFindWithComplexPropertyChainCondition',
				'shouldFindFirst',
				'shouldFindLast',
				'shouldFindBySimpleProperty',
				'shouldFindByPropertyChain'
			];

			tests.forEach( function( methodName:String, index:int, array:Array ):void
			{
				ts.addTest( new ArrayPeerTest( methodName ) );
			});

			return ts;
		}

		public function ArrayPeerTest( method:String )
		{
			super( method );
		}
		
		private var movies:Array = [
			{ name: 'Transformers', director: 'Michael Bay', released: new Date(2007, 5, 28), cast: [{name:'Shia LaBeouf'}, {name:'Megan Fox'}, {name:'Josh Duhamel'}, {name:'Rachael Taylor'}] },
			{ name: 'Oceans Thirteen', director: 'Steven Soderbergh', released: new Date(2007, 5, 14), cast: [{name:'George Clooney'}, {name:'Brad Pitt'}, {name:'Matt Damon'}] },
			{ name: 'Twelve Monkeys', director: 'Terry Gilliam', released: new Date(1996, 2, 14), cast: [{name: 'Bruce Willis'}, {name:'Brad Pitt'}, {name:'Madeleine Stowe'}] }
		];
		
		override public function setUp():void
		{
		}

		public function shouldFindWithSingleSimpleCondition():void
		{
			var result:Object = ArrayPeer.find( movies, { director: 'Michael Bay' } );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting correct result to be returned', 'Michael Bay', result.director );
		}
		
		public function shouldFindWithMultipleSimpleConditions():void
		{
			var result:Object = ArrayPeer.find( movies, { name: 'Transformers', director: 'Michael Bay' } );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting correct result to be returned', 'Michael Bay', result.director );
		}
		
		public function shouldFindWithSimplePropertyChainCondtion():void
		{
			var result:Array = ArrayPeer.find( movies, { 'released.fullYear': 2007 }, { find:ArrayPeer.ALL } );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting 2 results', 2, result.length );
		}
		
		public function shouldFindWithClassAsExpectedValue():void
		{
			fail('test not yet implemented');
		}
		
		public function shouldFindWithFunctionAsExpectedValue():void
		{
			// find movies with spaces in their names
			var result:Array = ArrayPeer.find( movies, 
				{ 
					name: function( movie:Object, name:String ):Boolean { return name.indexOf(' ') > -1; } 
				}, 
				{ find: ArrayPeer.ALL });
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting 2 results', 2, result.length );
			assertEquals( 'Expecting correct result to be returned', 'Oceans Thirteen', result[0].name );
			assertEquals( 'Expecting correct result to be returned', 'Twelve Monkeys', result[1].name );
		}
		
		public function shouldFindWithRegExpAsExpectedValue():void
		{
			// find movies beginning with Tr
			var result:Object = ArrayPeer.find( movies, { name: /^Tr.*/ } );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting correct result to be returned', 'Transformers', result.name );
		}
		
		public function shouldFindWithComplexPropertyChainCondition():void
		{
			var result:Object = ArrayPeer.find( movies, { 'cast.name': 'Megan Fox' } );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting correct result to be returned', 'Transformers', result.name );
		}
		
		public function shouldFindFirst():void
		{
			var result:Object = ArrayPeer.findFirst( movies, { name: 'Transformers' } );
			
			assertNotNull( 'Expecting the matching item', result );
			assertEquals( 'Expecting the correct item', 'Transformers', result.name )
		}
		
		public function shouldFindLast():void
		{
			var result:Object = ArrayPeer.findLast( movies, { 'cast.name': 'Brad Pitt' } );
			
			assertNotNull( 'Expecting the matching item', result );
			assertEquals( 'Expecting the correct item', 'Twelve Monkeys', result.name )			
		}
		
		public function shouldFindBySimpleProperty():void
		{
			var result:Object = ArrayPeer.findBy( movies, 'name', 'Twelve Monkeys' );
			
			assertNotNull( 'Expecting the matching item', result );
			assertEquals( 'Expecting correct result to be returned', 'Twelve Monkeys', result.name );
		}
		
		public function shouldFindByPropertyChain():void
		{
			var result:Array = ArrayPeer.findBy( movies, 'cast.name', 'Brad Pitt', {find: ArrayPeer.ALL} );
			
			assertNotNull( 'Expecting an Array of results', result );
			assertEquals( 'Expecting 2 results', 2, result.length );
			assertEquals( 'Expecting correct result to be returned', 'Oceans Thirteen', result[0].name );
			assertEquals( 'Expecting correct result to be returned', 'Twelve Monkeys', result[1].name );
		}
	}
}